﻿using System;
using System.Text;
using zTalk.Network;

namespace zTalk
{
    public partial class PacketHandlerClient : PacketHandlerBase, IPacketHandler
    {
        public void Handle(SocketBase client, Packet packet)
        {
            switch (packet.Opcode)
            {
                case Opcodes.PING:
                    handlePing(client, packet);
                    break;
                case Opcodes.PONG:
                    handlePong(client, packet);
                    break;
                case Opcodes.LOGIN:
                    handleLogin(client, packet);
                    break;
                case Opcodes.REGISTER:
                    handleRegister(client, packet);
                    break;
                case Opcodes.MESSAGE:
                    handleMessage(client, packet);
                    break;
                case Opcodes.USER_OFFLINE:
                    handleUserOffline(client, packet);
                    break;
                case Opcodes.ADD_FRIEND:
                    handleAddFriend(client, packet);
                    break;
                case Opcodes.REMOVE_FRIEND:
                    break;
                case Opcodes.GET_FRIENDS:
                    handleGetFriends(client, packet);
                    break;
                case Opcodes.USER_CHANGE:
                    handleChangeUser(client, packet);
                    break;
                case Opcodes.UPDATE_PROFILE:
                    handleUpdateProfile(client, packet);
                    break;
                case Opcodes.GET_PROFILE:
                    handleGetProfile(client, packet);
                    break;
                case Opcodes.UPDATE_PASSWORD:
                    handleUpdatePassword(client, packet);
                    break;
                case Opcodes.SAVE_AVATAR:
                    handleSaveAvatar(client, packet);
                    break;
                case Opcodes.GET_USER:
                    handleGetUser(client, packet);
                    break;
                case Opcodes.USER_LOGOUT:
                    handleUserLogout(client, packet);
                    break;
                case Opcodes.GET_MESSAGES:
                    break;
                /*case Opcodes.GET_AVATAR:
                    handleGetAvatar(client, packet);
                    break;*/
                /*case Opcodes.FILE_SEND:
                    handleFileSend(client, packet);
                    break;
                case Opcodes.FILE_ACCEPT:
                    handleFileAccept(client, packet);
                    break;
                case Opcodes.FILE_TRANSFER:
                    handleFileTransfer(client, packet);
                    break;*/

                default:
                    throw new Exception("Invalid operation code " + packet.Opcode.ToString());
            }
        }

        private void handlePing(SocketBase client, Packet packet)
        {
            DateTime d = DateTime.Parse(Encoding.UTF8.GetString(packet.Data));
            Packet p = Packet.Create(Opcodes.PONG, d.ToString());
            client.SendPacket(p);
        }

        private void handlePong(SocketBase client, Packet packet)
        {
            DateTime d = DateTime.Parse(Encoding.UTF8.GetString(packet.Data));
            TimeSpan interval = DateTime.Now - d;
        }

        private void handleLogin(SocketBase client, Packet packet)
        {
            string data = Encoding.UTF8.GetString(packet.Data);

            UserItem user = null;
            try
            {
                user = Json.Decode<UserItem>(data);
            }
            catch (Exception exc) 
            {
                //MessageBox.Show(exc.ToString());
            }

            onLogin(user);
        }

        private void handleRegister(SocketBase client, Packet packet)
        {
            string[] result = getData(packet);
            onRegister(result[0] == "ok");
        }

        private void handleMessage(SocketBase client, Packet packet)
        {
            MessageProto message = Json.Decode<MessageProto>(
                Encoding.UTF8.GetString(packet.Data)    
            );
            onMessage(message);
        }

        private void handleUserOffline(SocketBase client, Packet packet)
        {
            string[] data = getData(packet);
            onUserOffline(data[0]);
        }

        private void handleAddFriend(SocketBase client, Packet packet)
        {
            string data = Encoding.UTF8.GetString(packet.Data);

            UserItem user = null;
            try
            {
                user = Json.Decode<UserItem>(data);
            }
            catch { }

            onAddFriend(user);
        }

        private void handleGetFriends(SocketBase client, Packet packet)
        {
            string data = Encoding.UTF8.GetString(packet.Data);
            UserItem[] users = Json.Decode<UserItem[]>(data);
            onGetFriends(users);
        }

        private void handleChangeUser(SocketBase client, Packet packet)
        {
            string data = Encoding.UTF8.GetString(packet.Data);
            UserItem changes = Json.Decode<UserItem>(data);
            onUserChange(changes);
        }

        private void handleUpdateProfile(SocketBase client, Packet packet)
        {
            string[] data = getData(packet);
            onUpdateProfile(data[0]);
        }


        private void handleGetProfile(SocketBase client, Packet packet)
        {
            string[] data = getData(packet);
            onGetProfile(data);
        }

        private void handleUpdatePassword(SocketBase client, Packet packet)
        {
            string[] data = getData(packet);
            onUpdatePassword(data[0]);
        }

        private void handleSaveAvatar(SocketBase client, Packet packet)
        {
            string[] data = getData(packet);
            onSaveAvatar(data[0]);
        }

        private void handleFileSend(SocketBase client, Packet packet)
        {
            FileProto message = Json.Decode<FileProto>(
                Encoding.UTF8.GetString(packet.Data)
            );

            onFileSend(message);
        }

        private void handleFileAccept(SocketBase client, Packet packet)
        {
            FileProto message = Json.Decode<FileProto>(
                Encoding.UTF8.GetString(packet.Data)
            );
            onFileAccept(message);
        }

        private void handleFileTransfer(SocketBase client, Packet packet)
        {
            MessageProto message = Json.Decode<MessageProto>(
                Encoding.UTF8.GetString(packet.Data)
            );
            onFileTransfer(message);
        }

        private void handleGetUser(SocketBase client, Packet packet)
        {
            string data = Encoding.UTF8.GetString(packet.Data);

            UserItem user = null;
            try
            {
                user = Json.Decode<UserItem>(data);
            }
            catch { }

            onGetUser(user);
        }

        private void handleUserLogout(SocketBase client, Packet packet)
        {
            string[] data = getData(packet);
            onUserLogout(data[0]);
        }
    }
}